package com.zhongkun.datahome.core.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhongkun.datahome.common.core.domain.entity.*;
import com.zhongkun.datahome.common.enums.DataSettingLinkTypeEnum;
import com.zhongkun.datahome.common.exception.ServiceException;
import com.zhongkun.datahome.common.utils.SecurityUtils;
import com.zhongkun.datahome.core.domain.MiniProgramDataSetting;
import com.zhongkun.datahome.core.domain.SysRoleMenu;
import com.zhongkun.datahome.core.mapper.*;
import com.zhongkun.datahome.core.repository.SysMiniProgramDataSettingRepository;
import com.zhongkun.datahome.core.repository.TenantRepository;
import com.zhongkun.datahome.core.repository.TenantUserRepository;
import com.zhongkun.datahome.core.service.ISysConfigService;
import com.zhongkun.datahome.core.service.ISysRoleService;
import com.zhongkun.datahome.core.service.ITenantService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: lifengsheng
 * @Date: 2025/5/6 11:55
 * @Desc
 */
@Service
public class TenantServiceImpl implements ITenantService {
    @Resource
    private TenantRepository tenantRepository;

    @Resource
    private TenantUserRepository tenantUserRepository;

    @Resource
    private SysMiniProgramDataSettingRepository sysMiniProgramDataSettingRepository;

    @Resource
    private ISysConfigService sysConfigService;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private SysRoleDeptMapper sysRoleDeptMapper;

    @Override
    public IPage<Tenant> page(String tenantName, Integer pageNo, Integer pageSize) {
        Page<Tenant> page = tenantRepository.page(new Page<>(pageNo, pageSize), new LambdaQueryWrapper<Tenant>()
                .like(StringUtils.isNotBlank(tenantName), Tenant::getTenantName, tenantName)
                .orderByDesc(Tenant::getId));

        // 操作人
        tenantUserRepository.batchSetUserName(page.getRecords(), Tenant::getUpdateBy, Tenant::setOperatorName);
        return page;
    }

    @Override
    @Transactional
    public Long add(String tenantName) {
        if (Objects.nonNull(tenantRepository.getByName(tenantName))) {
            throw new ServiceException("商户名称已存在");
        }

        Tenant tenant = new Tenant();
        tenant.setTenantName(tenantName);
        tenantRepository.save(tenant);

        // 配置默认图标
        createDefaultDataSettings(tenant.getId());

        // 管理员添加商户
        tenantUserRepository.save(new TenantUser(1L, tenant.getId()));

        // 复制默认角色：管理员角色/问题反馈处理
        copyRoleFromDefault(tenant.getId());

        // 创建默认一级部门：项目名称
        createRootDept(tenant);
        return tenant.getId();
    }

    private void createRootDept(Tenant tenant) {
        SysDept rootDept = new SysDept();
        rootDept.setDeptName(tenant.getTenantName());
        rootDept.setParentId(0L);
        rootDept.setAncestors("0");
        rootDept.setCreateBy(SecurityUtils.getUsername());
        rootDept.setCreateTime(new Date());
        rootDept.setTenantId(tenant.getId());
        sysDeptMapper.insertDept(rootDept);
    }

    private void copyRoleFromDefault(Long tenantId) {
        // 获取默认角色
        String defaultRoleIdsConfig = sysConfigService.selectConfigByKey("copy.default.role.ids");
        if (StringUtils.isBlank(defaultRoleIdsConfig)) {
            return;
        }

        List<Long> defaultRoleIds = Arrays.stream(defaultRoleIdsConfig.split(","))
                .map(String::trim)
                .map(Long::parseLong)
                .collect(Collectors.toList());

        // 查角色列表
        List<SysRole> defaultRoleList = sysRoleMapper.selectRoleByRoleIds(defaultRoleIds);
        // 查图标列表
        List<MiniProgramDataSetting> dataSettingList = sysMiniProgramDataSettingRepository.listByTenantId(tenantId);
        Long[] dataSettingIds = dataSettingList.stream()
                .map(MiniProgramDataSetting::getId)
                .toArray(Long[]::new);
        // 查菜单列表
        Map<Long, List<SysRoleMenu>> roleMenuMap = sysRoleMenuMapper.listByRoleIds(defaultRoleIds).stream()
                .collect(Collectors.groupingBy(SysRoleMenu::getRoleId));

        // 创建商户角色
        for (SysRole role : defaultRoleList) {
            Long[] menuIds = roleMenuMap.getOrDefault(role.getRoleId(), Collections.emptyList()).stream()
                    .map(SysRoleMenu::getMenuId)
                    .toArray(Long[]::new);

            role.reset(tenantId);
            role.setDataSettingIds(dataSettingIds);
            role.setMenuIds(menuIds);
            sysRoleService.insertRole(role);
        }
    }

    private void createDefaultDataSettings(Long tenantId) {
        List<MiniProgramDataSetting> dataSettingList = new ArrayList<>();
        String dataSettingDefaultIconConfig = sysConfigService.selectConfigByKey("data.setting.default.icon.config");

        Map<String, String> map = JSON.parseObject(dataSettingDefaultIconConfig, Map.class);

        // 创建资料图标
        dataSettingList.add(MiniProgramDataSetting.of(DataSettingLinkTypeEnum.SIGN_FILE.getDesc(),
                map.get("signFile"), 1, DataSettingLinkTypeEnum.SIGN_FILE.getType(), tenantId));

        dataSettingList.add(MiniProgramDataSetting.of(DataSettingLinkTypeEnum.MATERIAL_LIST.getDesc(),
                map.get("materialList"), 2, DataSettingLinkTypeEnum.MATERIAL_LIST.getType(), tenantId));

        // 其他：图纸、验收报告、说明书、保修卡、常见问题
        dataSettingList.add(MiniProgramDataSetting.of("图纸",
                map.get("drawing"), 3, DataSettingLinkTypeEnum.OTHER.getType(), tenantId));

        dataSettingList.add(MiniProgramDataSetting.of("验收报告",
                map.get("checkAcceptReport"), 4, DataSettingLinkTypeEnum.OTHER.getType(), tenantId));

        dataSettingList.add(MiniProgramDataSetting.of("说明书",
                map.get("describeBook"), 5, DataSettingLinkTypeEnum.OTHER.getType(), tenantId));

        dataSettingList.add(MiniProgramDataSetting.of("保修卡",
                map.get("guaranteeCard"), 6, DataSettingLinkTypeEnum.OTHER.getType(), tenantId));

        dataSettingList.add(MiniProgramDataSetting.of("常见问题",
                map.get("normalProblem"), 7, DataSettingLinkTypeEnum.OTHER.getType(), tenantId));

        sysMiniProgramDataSettingRepository.saveBatch(dataSettingList);
    }

    @Override
    public void update(Long tenantId, String tenantName) {
        if (Objects.nonNull(tenantId)) {
            Tenant tenant = tenantRepository.getById(tenantId);
            if (Objects.isNull(tenant)) {
                throw new ServiceException("商户不存在");
            }

            if (!StringUtils.equals(tenant.getTenantName(), tenantName)) {
                Tenant byName = tenantRepository.getByName(tenantName);
                if (Objects.nonNull(byName)) {
                    throw new ServiceException("商户名称已存在");
                }
            }

            tenant.setTenantName(tenantName);
            tenantRepository.updateById(tenant);
        }
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            tenantRepository.removeBatchByIds(ids);
        }
    }
}
